﻿using System;
using System.Collections.Generic;
using System.Linq;
using Unis.Framework.ORM.Attributes;
using Unis.Framework.RuleBase.Common;
using KingRoad.EPM.PersonnelLogEntity;

namespace KingRoad.EPM.PersonnelLogDAL
{
    /// <summary>
    /// 作用：数据库操作实体对象基础业务封装
    /// </summary>
    /// <author>
    ///   <name>王强</name>
    ///   <date>2016年11月10日</date>
    /// </author>
    /// <typeparam name="T">实体类</typeparam>
    public class BaseService<T> : IBaseService<T> where T : BaseEntity, new()
    {
        private readonly string _tableName = "";
        //SqlConfigFile文件中的文件名称
        private readonly string _modelMapXmlName = "";
        //映射的表的主键
        private readonly string _modelMapPrimaryKey = "";

        public BaseService()
        {
            var modelAttri = typeof(T).GetCustomAttributes(typeof(ModelMapAttribute), false).FirstOrDefault() as ModelMapAttribute;
            _modelMapXmlName = modelAttri != null ? modelAttri.XmlFileName : "";
            _tableName = modelAttri != null ? modelAttri.TableName : "";
            if (!string.IsNullOrEmpty(_modelMapXmlName))
            {
                var arrayName = _modelMapXmlName.Split('_').ToList();
                var tempXmlName = "";
                arrayName.ForEach(t =>
                {
                    tempXmlName += t.Substring(0, 1).ToUpper() + t.Substring(1).ToLower();
                });
                _modelMapXmlName = tempXmlName;
            }



            _modelMapPrimaryKey = modelAttri != null ? modelAttri.PrimaryKeys[0] : "";
        }


        /// <summary>
        /// 查询表中的实体对象
        /// </summary>
        /// <param name="condition">查询条件（可以直接写SQL语句）</param>
        /// <returns></returns>
        public virtual List<T> GetEntityList(string condition = " 1=1 ")
        {
            if (String.IsNullOrEmpty(_modelMapXmlName)) return null;

            if (String.IsNullOrEmpty(condition))
                condition = " 1=1 ";
            var entityList = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<T>(_modelMapXmlName, "SelectObject", condition);
            return entityList;
        }

        /// <summary>
        /// 根据表的主键，获取一个实体对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetEntityById(Guid id)
        {
            if (String.IsNullOrEmpty(_modelMapXmlName) || id == Guid.Empty) return default(T);
            var sqlStr = String.Format(" {0} = '{1}'", _modelMapPrimaryKey, id.ToString());
            var entity = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<T>(_modelMapXmlName, "SelectObject", sqlStr).FirstOrDefault();
            return entity;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int InsertEntity(T entity)
        {
            if (String.IsNullOrEmpty(_modelMapXmlName)) return 0;
            int ret = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQueryByEntity(_modelMapXmlName, "AddObject", entity);
            return ret;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int UpdateEntity(T entity)
        {
            if (String.IsNullOrEmpty(_modelMapXmlName)) return 0;
            int ret = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQueryByEntity(_modelMapXmlName, "UpdateObject", entity);
            return ret;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DeleteEntity(Guid id)
        {
            if (String.IsNullOrEmpty(_modelMapXmlName)) return 0;
            int ret = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery(_modelMapXmlName, "DeleteObject", id);
            return ret;
        }
        /// <summary>
        /// 删除实体对象
        /// 说明： 因Guid 类型的ID无法实现删除，所以在此添加string类型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DeleteEntityByStringID(string id)
        {
            if (String.IsNullOrEmpty(_modelMapXmlName)) return 0;
            int ret = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery(_modelMapXmlName, "DeleteObject", id);
            return ret;
        }
        /// <summary>
        ///删除实体对象（批量删除 ）
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DeleteEntityByMultiStringID(string id)
        {
            var ids = "";
            id.Split(',').ToList().ForEach(t =>
            {
                ids += "'" + t + "',";
            });
            if (!String.IsNullOrEmpty(ids))
            {
                ids = ids.Substring(0, ids.Length - 1);
            }
            if (String.IsNullOrEmpty(_modelMapXmlName)) return 0;
            int ret = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery(_modelMapXmlName, "DeleteObjectMulti", ids);
            return ret;
        }



        public List<T> GetEntityListByContion(int numCurrentPage, int numPerPage, string orderByField, out int totalRecord, string condition = " 1=1 ")
        {
            if (String.IsNullOrEmpty(_modelMapXmlName))
            {
                totalRecord = 0; return null;
            }

            if (String.IsNullOrEmpty(condition))
                condition = " 1=1 ";
            //检索数据的总条数
            totalRecord = Convert.ToInt32(DatabaseExcuteByXmlHelper.NewInstance.ExecuteScalar(_modelMapXmlName, "SelectCountObject", condition));


            var startNum = (numCurrentPage - 1) * numPerPage + 1;
            var endNum = numCurrentPage * numPerPage >= totalRecord ? totalRecord : numCurrentPage * numPerPage;


            var sqlStr = string.Format(@"SELECT  *
                                         FROM    (SELECT * ,ROW_NUMBER() OVER ( ORDER BY {0} ASC ) AS RowNumber
                                                 FROM  {1} AS a WHERE {2}) AS b
                                         WHERE   b.RowNumber BETWEEN {3} AND {4};", "a." + orderByField, _tableName, condition, startNum, endNum);

            var splitList = DatabaseExcuteBySql.QueryBySql<T>(sqlStr);

            return splitList;
        }


        public List<T> GetEntityListByContionRe(int numCurrentPage, int numPerPage, string orderByField, out int totalRecord, string condition = " 1=1 ",string desc="desc")
        {
            if (String.IsNullOrEmpty(_modelMapXmlName))
            {
                totalRecord = 0; return null;
            }

            if (String.IsNullOrEmpty(condition))
                condition = " 1=1 ";
            //检索数据的总条数
            totalRecord = DatabaseExcuteBySql.ExecuteScalar<int>("SELECT COUNT(1) FROM  " + _tableName + " WHERE " + condition + "");


            var startNum = (numCurrentPage - 1) * numPerPage + 1;
            var endNum = numCurrentPage * numPerPage >= totalRecord ? totalRecord : numCurrentPage * numPerPage;


            var sqlStr = string.Format(@"SELECT  *
                                         FROM    (SELECT * ,ROW_NUMBER() OVER ( ORDER BY {0} {5} ) AS RowNumber
                                                 FROM  {1} AS a WHERE {2}) AS b
                                         WHERE   b.RowNumber BETWEEN {3} AND {4};", "a." + orderByField, _tableName, condition, startNum, endNum,desc);

            var splitList = DatabaseExcuteBySql.QueryBySql<T>(sqlStr);

            return splitList;
        }
        public List<K> GetEntityListByContionRe<K>(int numCurrentPage, int numPerPage, string orderByField, List<K> list, string desc = "desc") where K : new()
        {
            var orderByList = new List<K>();
            if (desc == "asc")
            {
                orderByList = list.OrderBy(t =>
                {
                    var value = t.GetType().GetProperty(orderByField).GetValue(t, null);

                    var fullName = t.GetType().GetProperty(orderByField).PropertyType.FullName;

                    if (fullName == "System.String")
                        return Convert.ToString(value);
                    if (fullName == "System.DateTime")
                        return Convert.ToDateTime(value);

                    return value;
                }).ToList();
            }
            else
            {
                orderByList = list.OrderByDescending(t =>
                {
                    var value = t.GetType().GetProperty(orderByField).GetValue(t, null);

                    var fullName = t.GetType().GetProperty(orderByField).PropertyType.FullName;

                    if (fullName == "System.String")
                        return Convert.ToString(value);
                    if (fullName == "System.DateTime")
                        return Convert.ToDateTime(value);

                    return value;
                }).ToList();
            }
            var tempBusiness = new List<TempBusiness<K>>();
            var orderIndex = 1;
            orderByList.ForEach(t =>
            {
                tempBusiness.Add(new TempBusiness<K>
                {
                    k = t,
                    Order = orderIndex
                });
                orderIndex++;
            });
            var totalRecord = tempBusiness.Count;
            var startNum = (numCurrentPage - 1) * numPerPage + 1;
            var endNum = numCurrentPage * numPerPage >= totalRecord ? totalRecord : numCurrentPage * numPerPage;
            var splitList = tempBusiness.TakeWhile(t => t.Order >= startNum && t.Order <= endNum).ToList();

            var result = new List<K>();
            splitList.ForEach(t => result.Add(t.k));

            return result;
        }
        //public GridData GetGridData(string view, string where, string sortname, string sortorder, int? pagenumber, int? pagesize, FilterParam[] parms, string sql)
        //{
        //    var total = GetGridTotal(view, where, parms, sql);
        //    var data = GetGridRows(view, where, sortname, sortorder, pagenumber, pagesize, total, parms, sql);
        //    return new GridData()
        //    {
        //        Data = data,
        //        Total = total
        //    };
        //}

        //public int GetGridTotal(string view, string where, FilterParam[] parms, string sql)
        //{
        //    using (SqlConnection sqlConnection = new SqlConnection(SystemConfig.GetValueByKey("ConnectionString")))
        //    {
        //        string commandText = "SELECT count(1) FROM {0} WHERE {1} {2}".FormatWith(view, where.IsNullOrEmpty() ? "1=1" : where, sql.IsNullOrEmpty() ? "" : sql);
        //        using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
        //        {
        //            if (parms != null)
        //            {
        //                foreach (var parm in parms)
        //                {
        //                    SqlParameter sqlParameter = new SqlParameter();
        //                    sqlParameter.ParameterName = "@" + parm.Name;
        //                    sqlParameter.Value = parm.Value;
        //                    sqlCommand.Parameters.Add(sqlParameter);
        //                }
        //            }
        //            sqlConnection.Open();
        //            int count = Convert.ToInt32(sqlCommand.ExecuteScalar());
        //            sqlConnection.Close();
        //            return count;
        //        }
        //    }
        //}

        ///// <summary>
        ///// 默认的 N-M行    分页方案： 
        ///// 1，根据条件和排序 检索出全部前M行数据 
        ///// 2，对这M行数据反转(排序反转) 
        ///// 3，对反转完的数据，取前 M-N+1 行
        ///// 4，取完数据以后，再次反转
        ///// 如：select * from (select top [M-N+1] * from (select top [M] * from 表 [order by id desc]) [order by id asc]) [order by id desc]
        ///// </summary>
        ///// <param name="view"></param>
        ///// <param name="where"></param>
        ///// <param name="sortname"></param>
        ///// <param name="sortorder"></param>
        ///// <param name="pagenumber"></param>
        ///// <param name="pagesize"></param>
        ///// <param name="parms"></param>
        ///// <returns></returns>
        //public ResultData GetGridRows(string view, string where, string sortname, string sortorder, int? pagenumber, int? pagesize, int? total, FilterParam[] parms, string sql)
        //{
        //    string commandText = "";
        //    bool pagable = pagenumber.HasValue && pagesize.HasValue;
        //    bool sortable = !sortname.IsNullOrEmpty() && !sortorder.IsNullOrEmpty();
        //    bool whereIsNullOrEmpty = where.IsNullOrEmpty();
        //    bool sortorderIsASC = sortorder.EqualsTo("asc");
        //    if (pagable)
        //    {
        //        int count = pagenumber.Value * pagesize.Value;
        //        if (total.Value < count)
        //        {
        //            pagesize = (pagesize.Value - (count - total.Value));
        //        };
        //        string sqlText = "SELECT TOP {2} * FROM [{0}] WHERE {1} {3}".FormatWith(view, whereIsNullOrEmpty ? "1=1" : where, count.ToString(), sql.IsNullOrEmpty() ? "" : sql);
        //        if (view.IndexOf("as") > 0)
        //        {
        //            sqlText = "SELECT TOP {2} * FROM {0} WHERE {1} {3}".FormatWith(view, whereIsNullOrEmpty ? "1=1" : where, count.ToString(), sql.IsNullOrEmpty() ? "" : sql);
        //        }
        //        commandText = " SELECT * FROM (SELECT TOP {PAGESIZE} * FROM ({OLDSQL} {ORDER}) AS tmptableinner {REVORDER}) AS tmptableouter {ORDER} ";
        //        commandText = commandText.Replace("{PAGESIZE}", pagesize.Value.ToString());
        //        if (sortable)
        //        {
        //            commandText = commandText.Replace("{ORDER}", string.Concat("ORDER BY ", sortname, " ", sortorderIsASC ? "ASC" : "DESC"));
        //            commandText = commandText.Replace("{REVORDER}", string.Concat("ORDER BY ", sortname, " ", sortorderIsASC ? "DESC" : "ASC"));
        //        }
        //        else
        //        {
        //            throw new Exception("必须指定一个排序条件");
        //        }
        //        commandText = commandText.Replace("{OLDSQL}", sqlText);
        //    }
        //    else
        //    {
        //        commandText = "SELECT * FROM [{VIEW}] WHERE {WHERE} {SQLTEXT}";
        //        if (view.IndexOf("as") > 0)
        //        {
        //            commandText = "SELECT * FROM {VIEW} WHERE {WHERE} {SQLTEXT}";
        //        }
        //        if (sortable)
        //        {
        //            commandText += string.Concat(" ORDER BY ", sortname, " ", sortorderIsASC ? "ASC" : "DESC");
        //        }
        //        commandText = commandText.Replace("{VIEW}", view);
        //        commandText = commandText.Replace("{WHERE}", whereIsNullOrEmpty ? "1=1" : where);
        //        commandText = commandText.Replace("{SQLTEXT}", sql.IsNullOrEmpty() ? "" : sql);
        //    }

        //    ResultData resultData = new ResultData();
        //    using (SqlConnection sqlConnection = new SqlConnection(SystemConfig.GetValueByKey("ConnectionString")))
        //    {
        //        using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(commandText, sqlConnection))
        //        {
        //            if (parms != null)
        //            {
        //                foreach (var parm in parms)
        //                {
        //                    SqlParameter sqlParameter = new SqlParameter();
        //                    sqlParameter.ParameterName = "@" + parm.Name;
        //                    sqlParameter.Value = parm.Value;
        //                    sqlDataAdapter.SelectCommand.Parameters.Add(sqlParameter);
        //                }
        //            }
        //            sqlDataAdapter.Fill(resultData, resultData._ResultData.TableName);
        //        }
        //    }
        //    return resultData;
        //}


        //public ResultData GetSelectBySQL(string commandText, FilterParam[] parms)
        //{
        //    ResultData resultData = new ResultData();
        //    using (SqlConnection sqlConnection = new SqlConnection(SystemConfig.GetValueByKey("ConnectionString")))
        //    {
        //        using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
        //        {
        //            if (parms != null)
        //            {
        //                foreach (var parm in parms)
        //                {
        //                    SqlParameter sqlParameter = new SqlParameter();
        //                    sqlParameter.ParameterName = "@" + parm.Name;
        //                    sqlParameter.Value = parm.Value;
        //                    sqlCommand.Parameters.Add(sqlParameter);
        //                }
        //            }
        //            using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand))
        //            {
        //                sqlDataAdapter.Fill(resultData, resultData._ResultData.TableName);
        //            }
        //        }
        //    }
        //    return resultData;
        //}

        /// <summary>
        /// 删除实体对象
        /// 说明： 因Guid 类型的ID无法实现删除，所以在此添加string类型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DeleteBySql(string sql)
        {
            if (String.IsNullOrEmpty(_modelMapXmlName)) return 0;
            int ret = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery(_modelMapXmlName, "DeleteObjectBySql", sql);
            return ret;
        }
    }
    public class TempBusiness<K> where K : new()
    {
        public K k { get; set; }

        public int Order { get; set; }
    }
}
